package fag.core.collision;

import java.awt.geom.AffineTransform;
import java.io.Serializable;

import fag.core.geometry.Rectangle2D;
import fag.core.geometry.Vector2D;

/**
 * Interface à implémenter par les objets dont on souhaite détecter les collisions grâce
 * aux agorithmes GJK, EPA.
 * @author lumz
 */
public abstract class Hitbox implements Serializable, Cloneable {

	Quadtree.Quadrant quadrant = null;
	
	private static final long serialVersionUID = -4818608855282535973L;
	
	@Override
	public Hitbox clone() {
		
		Hitbox hitbox = null;
		
		try {
			hitbox = (Hitbox) super.clone();	
		}
		catch (CloneNotSupportedException cloneNotSupportedException) {
			cloneNotSupportedException.printStackTrace();
		}
		
		return hitbox;
	}
	
	/**
	 * Obtenir la collision entre deux boîtes de collision.
	 * @param hitbox La boîte de collision impliquée.
	 * @return La collision entre les deux boîtes de collision.
	 */
	public Collision getCollision(Hitbox hitbox) {
		
		Collision collision = new Collision(this, hitbox);
		
		// Pas de collision possible
		if(quadrant != null && hitbox.quadrant != null && quadrant == hitbox.quadrant) {
			collision.mayCollide = false;
			return collision;
		}
		
		return collision;
	}
	
	/**
	 * Obtenir la boîte englobante.
	 * @return La boîte englobante de la hitbox.
	 */
	public abstract Rectangle2D getBounds();
	
	/**
	 * Assistance pour l'algorithme de détection GJK et EPA. Doit renvoyer le sommet le plus éloigné
	 * sur le vecteur d'assistance.
	 * @param d Le vecteur d'assistance.
	 * @return Le sommet le plus éloigné sur le vecteur d'assistance.
	 */
	public abstract Vector2D supportMapping(Vector2D d);
	
	/**
	 * Transformer cette boîte de collision.
	 * @param transformation La transformation à appliquer.
	 * @return Une boîte de collision transformée.
	 */
	public abstract Hitbox transform(AffineTransform transformation);
}
